package com.csu.letaobackend.serviceM.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.csu.letaobackend.bean.*;
import com.csu.letaobackend.commom.CommonResponse;
import com.csu.letaobackend.persistence.*;
import com.csu.letaobackend.serviceM.OrderMService;
import com.csu.letaobackend.vo.OrderItemVO;
import com.csu.letaobackend.vo.OrderVO;
import com.csu.letaobackend.vo.RefundserviceVO;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

@Service
@MapperScan("com.csu.letaobackend.persistence")
public class OrderMServiceImpl implements OrderMService {

      @Autowired
      OrderDao orderDao;

      @Autowired
      OrderItemDao orderitemDao;

      @Autowired
      ItemDao itemDao;

      @Autowired
      ShopDao shopDao;

      @Autowired
      ReceivingDao receivingDao;

      @Autowired
      PictureDao pictureDao;

      @Autowired
      RefundserviceDao refundserviceDao;

      @Autowired
      CouponDao couponDao;

      @Autowired
      SpecialofferDao specialofferDao;

      @Override
      public CommonResponse<IPage<OrderVO>> getAllOrders(int pageid, int pagesize, int status) {

            IPage<Order> orderIPage = new Page<>(pageid, pagesize);
            QueryWrapper queryWrapper = new QueryWrapper();
            if (status != -1) {
                  queryWrapper.eq("status", status);
            }
            orderDao.selectPage(orderIPage, queryWrapper);

            List<OrderVO> orderVOList = new ArrayList<>();
            for (Order order : orderIPage.getRecords()) {
                  orderVOList.add(entityToVO(order));
            }
            IPage<OrderVO> orderVOIPage = new Page<>(pageid, pagesize);
            orderVOIPage.setTotal(orderIPage.getTotal());
            orderVOIPage.setRecords(orderVOList);

            return CommonResponse.createForSuccess(orderVOIPage);
      }


      @Override
      public CommonResponse<OrderVO> getOrderByOrderId(String orderid) {
            Order order = orderDao.selectById(orderid);
            return CommonResponse.createForSuccess(entityToVO(order));
      }

      @Override
      public CommonResponse<OrderVO> updateOrderStatus(String orderid, int status) {
            UpdateWrapper updateWrapper = new UpdateWrapper();
            updateWrapper.eq("orderid", orderid);
            int status1 = orderDao.selectById(orderid).getStatus();
            updateWrapper.set("status", status);
            if (orderDao.selectById(orderid) == null)
                  return CommonResponse.createForError("不存在该订单");
            if (status == -1) //取消订单
                  orderDao.delete(updateWrapper);
            if (status == 1) {//由未付款（0）改为已付款（1）（买家付款）
                  if (status1 == 0) {
                        updateWrapper.set("ispay", 1);
                  } else
                        CommonResponse.createForSuccessMessage("付款失败");
            }


            orderDao.update(null, updateWrapper);
            return CommonResponse.createForSuccessMessage("更新成功");
      }

      @Override
      public CommonResponse<RefundserviceVO> getRefundservice(String orderid) {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("orderid",orderid);
            Refundservice refundservice = refundserviceDao.selectOne(queryWrapper);

            return CommonResponse.createForSuccess(entityToVO(refundservice));
      }

      @Override
      public CommonResponse<IPage<RefundserviceVO>> getRefundservices(int pageid, int pagesize) {
            IPage<Refundservice> refundserviceIPage = new Page<>(pageid, pagesize);
            refundserviceDao.selectPage(refundserviceIPage, null);
            List<RefundserviceVO> refundserviceVOList = new ArrayList<>();
            for (Refundservice refundservice : refundserviceIPage.getRecords()) {
                  refundserviceVOList.add(entityToVO(refundservice));
            }
            IPage<RefundserviceVO> refundserviceVOIPage = new Page<>(pageid, pagesize);
            refundserviceVOIPage.setTotal(refundserviceIPage.getTotal());
            refundserviceVOIPage.setRecords(refundserviceVOList);

            return CommonResponse.createForSuccess(refundserviceVOIPage);
      }

      @Override
      public CommonResponse<Refundservice> addRefundservice(String orderid, String refundreason) {
            UpdateWrapper updateWrapper = new UpdateWrapper();
            updateWrapper.eq("orderid", orderid);
            if (refundserviceDao.selectOne(updateWrapper) == null) {

                  Refundservice refundservice = new Refundservice();
                  refundservice.setServiceid(getMaxServiceId() + 1);
                  refundservice.setOrderid(orderid);
                  refundservice.setRefundreason(refundreason);
                  refundservice.setRefusalreason("");
                  refundservice.setRefundtime(new Date());
                  refundserviceDao.insert(refundservice);
                  return CommonResponse.createForSuccess(refundservice);
            } else {
                  updateWrapper.set("refundreason", refundreason);
                  refundserviceDao.update(null, updateWrapper);
                  return CommonResponse.createForSuccess(refundserviceDao.selectOne(updateWrapper));
            }
      }

      @Override
      public CommonResponse<Refundservice> refuseRefundservice(String orderid, String refusalreason) {
            UpdateWrapper updateWrapper = new UpdateWrapper();
            updateWrapper.eq("orderid", orderid);
            updateWrapper.set("refusalreason", refusalreason);
            refundserviceDao.update(null, updateWrapper);
            return CommonResponse.createForSuccess(refundserviceDao.selectOne(updateWrapper));
      }


      @Override
      public CommonResponse<List<OrderVO>> getOrdersBySellers(String username, int status) {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("sellername", username);
            List<Shop> shopList = shopDao.selectList(queryWrapper);
            List<Integer> list = new ArrayList<>();
            for (Shop shop : shopList) {
                  list.add(shop.getShopid());
            }
            QueryWrapper queryWrapper1 = new QueryWrapper();
            queryWrapper1.in("shopid", list);
            if (status != -1) {
                  queryWrapper1.eq("status", status);
            }

            List<OrderVO> orderVOList = new ArrayList<>();
            List<Order> orderList = orderDao.selectList(queryWrapper1);
            for (Order order : orderList) {
                  orderVOList.add(entityToVO(order));
            }
            return CommonResponse.createForSuccess(orderVOList);
      }

      @Override
      public CommonResponse<List<OrderVO>> getOrdersByShopId(int shopid, int status) {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("shopid", shopid);
            if (status != -1) {
                  queryWrapper.eq("status", status);
            }

            List<OrderVO> orderVOList = new ArrayList<>();
            List<Order> orderList = orderDao.selectList(queryWrapper);
            for (Order order : orderList) {
                  orderVOList.add(entityToVO(order));
            }
            return CommonResponse.createForSuccess(orderVOList);
      }

      private OrderVO entityToVO(Order order) {
            OrderVO orderVO = new OrderVO();
            orderVO.setOrderid(order.getOrderid());
            orderVO.setShopid(order.getShopid());
            orderVO.setUsername(order.getUsername());
            orderVO.setShopname(shopDao.selectById(order.getShopid()).getName());
            orderVO.setRecevingid(order.getRecevingid());
            orderVO.setStatus(order.getStatus());
            orderVO.setRecevingtime(order.getRecevingtime());
            orderVO.setOrdertime(order.getOrdertime());
            orderVO.setIsevaluate(order.getIsevaluate());
            orderVO.setIspay(order.getIspay());

            Receiving receving = receivingDao.selectById(order.getRecevingid());
            orderVO.setReceivingaddr(receving.getAddrcoutry() + receving.getAddrprovince() + receving.getAddrcouty() + receving.getAddrdetails());
            orderVO.setContactphone(receving.getContactphone());
            orderVO.setRecivename(receving.getReceivename());

            List<OrderItemVO> orderItemVOList = new ArrayList<>();
            UpdateWrapper updateWrapper = new UpdateWrapper();
            updateWrapper.eq("orderid", order.getOrderid());
            List<OrderItem> orderItemList = orderitemDao.selectList(updateWrapper);
            for (OrderItem orderitem : orderItemList) {
                  orderItemVOList.add(entityToVO(orderitem));
            }
            orderVO.setOrderItemVOList(orderItemVOList);
            orderVO.setCouponid(order.getCouponid());
            //设置coupondiscount
            if (order.getCouponid() == 0)
                  orderVO.setCoupondiscount(0);
            else {
                  double discount = couponDao.selectById(order.getCouponid()).getDiscount();
                  orderVO.setCoupondiscount(discount);
            }

            double ordertotal = 0;
            double orderdiscount = 0;
            for (OrderItemVO orderItemVO : orderItemVOList) {
                  ordertotal += orderItemVO.getAllprice();
                  orderdiscount += orderItemVO.getDiscount();
            }
            orderVO.setOrdertotal(ordertotal);
            orderVO.setOrderdiscount(orderdiscount);
            double actualpay = ordertotal - orderdiscount - orderVO.getCoupondiscount();
            orderVO.setActualpay(actualpay);

            if(refundserviceDao.selectOne(updateWrapper)==null)
                  orderVO.setServiceid(0);
            else
                  orderVO.setServiceid(refundserviceDao.selectOne(updateWrapper).getServiceid());
            return orderVO;
      }

      private OrderItemVO entityToVO(OrderItem orderitem) {
            Picture picture = pictureDao.selectById(orderitem.getItemid());
            Item item = itemDao.selectById(orderitem.getItemid());
            OrderItemVO orderitemVO = new OrderItemVO();
            orderitemVO.setOrderid(orderitem.getOrderid());
            orderitemVO.setItemid(orderitem.getItemid());
            orderitemVO.setDescription(item.getDescription());
            orderitemVO.setNum(orderitem.getNum());
            orderitemVO.setPrice(orderitem.getNewprice());
            orderitemVO.setAllprice(orderitem.getNewprice() * orderitem.getNum());
            orderitemVO.setAttrdescription(orderitem.getAttrdescription());
            orderitemVO.setSrc(picture.getSrc());
            if (specialofferDao.selectById(orderitem.getItemid()) != null)
                  orderitemVO.setSpecialrate(specialofferDao.selectById(orderitem.getItemid()).getRate());
            else
                  orderitemVO.setSpecialrate(1);
            orderitemVO.setDiscount(orderitem.getNewprice() * orderitem.getNum() * (1 - orderitemVO.getSpecialrate()));
            return orderitemVO;
      }

      private RefundserviceVO entityToVO(Refundservice refundservice) {
            RefundserviceVO refundserviceVO = new RefundserviceVO();
            refundserviceVO.setServiceid(refundservice.getServiceid());
            refundserviceVO.setOrderid(refundservice.getOrderid());
            refundserviceVO.setRefundreason(refundservice.getRefundreason());
            refundserviceVO.setRefusalreason(refundservice.getRefusalreason());
            refundserviceVO.setRefundtime(refundservice.getRefundtime());
            refundserviceVO.setOrderVO(getOrderByOrderId(refundservice.getOrderid()).getData());
            return refundserviceVO;
      }

      private int getMaxServiceId() {
            List<Integer> list = new ArrayList<>();
            for (Refundservice refundservice : refundserviceDao.selectList(null)) {
                  list.add(refundservice.getServiceid());
            }
            if (list.size() == 0)
                  return 0;
            return Collections.max(list);
      }
}
